package com.wlyuan.open.domain.source.dispatcher.conversion;

import com.wlyuan.core.exception.AssertUtils;
import com.wlyuan.core.exception.ValueError;
import com.wlyuan.open.constants.CarrierTypeEnum;
import com.wlyuan.open.dto.OpenCombineSyncDTO;
import com.wlyuan.open.infrastructure.exception.SourceValueErrorException;
import com.wlyuan.open.remote.facade.AddressDTO;
import com.wlyuan.open.remote.facade.constants.Constants;
import com.wlyuan.open.utils.LongUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author lijing
 * @description
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class OpenDispatcherCombineConversion implements OpenDispatcherConversion<OpenCombineSyncDTO> {
    private final BaseOpenDispatcherConversion baseOpenDispatcherConversion;

    @Override
    public void convert(OpenCombineSyncDTO source) {
        //租户id转换
        tenantConvert(source);
        //拼车单子单
        transportIdConvert(source);
        //调度人,接收人,创建人,修改人,客户,承运方,关闭信息 创建人 修改人
        infoConvert(source);
        //合约
        templateConvert(source);
        //地区转换
        areaConvert(source);
    }

    private void tenantConvert(OpenCombineSyncDTO source) {
        var tenant = source.getTenantId();
        if (LongUtils.notNullLong(tenant)) {
            var tenantId = baseOpenDispatcherConversion.tenant(tenant);
            AssertUtils.assertNotNull(tenantId, new ValueError("OpenCombineSyncDTO租户不存在:" + tenant), source);
            source.setTenantId(tenantId);
        }
        //客户租户
        var cTenant = source.getCustomerTenantId();
        if (LongUtils.notNullLong(cTenant)) {
            var tenantId = baseOpenDispatcherConversion.tenant(cTenant);
            AssertUtils.assertNotNull(tenantId, new ValueError("OpenCombineSyncDTO 客户租户不存在:" + cTenant), source);
            source.setCustomerTenantId(tenantId);
        }
        //承运方租户
    }

    private void transportIdConvert(OpenCombineSyncDTO source) {
        var transportIds = source.getTransportIds();
        if (!CollectionUtils.isEmpty(transportIds)) {
            var result = transportIds.stream().map(transportId -> {
                var id = baseOpenDispatcherConversion.transport(transportId);
                if (id == null) {
                    throw new SourceValueErrorException("OpenCombineSyncDTO子单不存在:" + transportId);
                }
                return id;
            }).collect(Collectors.toList());
            source.setTransportIds(result);
        }
    }

    private void infoConvert(OpenCombineSyncDTO source) {
        //调度人
        if (LongUtils.notNullLong(source.getDispatchBy())) {
            var dispatcherBy = baseOpenDispatcherConversion.user(source.getDispatchBy());
            AssertUtils.assertNotNull(dispatcherBy, new ValueError("OpenCombineSyncDTO调度人不存在:" + source.getDispatchBy()), source);
            source.setDispatchBy(dispatcherBy);
        }
        //接收人
        if (LongUtils.notNullLong(source.getAcceptBy())) {
            var acceptBy = baseOpenDispatcherConversion.user(source.getAcceptBy());
            AssertUtils.assertNotNull(acceptBy, new ValueError("OpenCombineSyncDTO接收人不存在:" + source.getAcceptBy()), source);
            source.setAcceptBy(acceptBy);
        }
        //创建人
        if (LongUtils.notNullLong(source.getCreateBy())) {
            var createBy = baseOpenDispatcherConversion.user(source.getCreateBy());
            AssertUtils.assertNotNull(createBy, new ValueError("OpenCombineSyncDTO创建人不存在:" + source.getCreateBy()), source);
            source.setCreateBy(createBy);
        }
        //修改人
        if (LongUtils.notNullLong(source.getUpdateBy())) {
            var updateBy = baseOpenDispatcherConversion.user(source.getUpdateBy());
            AssertUtils.assertNotNull(updateBy, new ValueError("OpenCombineSyncDTO修改人不存在:" + source.getUpdateBy()), source);
            source.setUpdateBy(updateBy);
        }
        //客户
        if (LongUtils.notNullLong(source.getCustomerId())) {
            var customer = baseOpenDispatcherConversion.customer(source.getCustomerId(), source.getCustomerType(), source.getCustomerTenantId());
            AssertUtils.assertNotNull(customer, new ValueError("OpenCombineSyncDTO客户不存在:" + source.getCustomerId() + "," + source.getCustomerType() + "," + source.getCustomerTenantId()), source);
            source.setCustomerId(customer.getCustomerId());
            if (StringUtils.isNotBlank(customer.getCustomerName())) {
                source.setCustomerName(customer.getCustomerName());
            }
        }
        //承运方
        var carrierId = source.getCarrierId();
        var carrierType = source.getCarrierType();
        if (LongUtils.notNullLong(carrierId) || CarrierTypeEnum.isMyself(carrierType) || CarrierTypeEnum.isDriver(carrierType)) {
            var supplier = baseOpenDispatcherConversion.carrier(carrierId, carrierType, source.getTenantId());
            AssertUtils.assertNotNull(supplier, new ValueError("OpenCombineSyncDTO承运方不存在:" + carrierId + "," + carrierType + "," + source.getTenantId()), source);
            source.setCarrierId(supplier.getCarrierId());
            source.setCarrierType(supplier.getCarrierType());
            if (StringUtils.isNoneBlank(supplier.getCarrierContactName())) {
                source.setCarrierContactName(supplier.getCarrierContactName());
            }
            if (StringUtils.isNotBlank(supplier.getCarrierPhone())) {
                source.setCarrierPhone(supplier.getCarrierPhone());
            }
            if (StringUtils.isNoneBlank(supplier.getCarrierName())) {
                source.setCarrierName(supplier.getCarrierName());
            }
        }
        //关闭操作人
        var closeInfo = source.getClose();
        Optional.ofNullable(closeInfo).ifPresent(close -> {
            //创建人
            if (LongUtils.notNullLong(close.getCreateBy())) {
                var createBy = baseOpenDispatcherConversion.user(close.getCreateBy());
                AssertUtils.assertNotNull(createBy, new ValueError("OpenCombineSyncDTO 关闭信息创建人不存在:" + close.getCreateBy()), source);
                close.setCreateBy(createBy);
            }
            //修改人
            if (LongUtils.notNullLong(close.getUpdateBy())) {
                var updateBy = baseOpenDispatcherConversion.user(close.getUpdateBy());
                AssertUtils.assertNotNull(updateBy, new ValueError("OpenCombineSyncDTO 关闭信息修改人不存在:" + close.getUpdateBy()), source);
                close.setUpdateBy(updateBy);
            }
            //关单审核租户
            var tenant = close.getToTenantId();
            if (LongUtils.notNullLong(tenant)) {
                var tenantId = baseOpenDispatcherConversion.tenant(tenant);
                AssertUtils.assertNotNull(tenantId, new ValueError("OpenCombineSyncDTO 关单审核租户不存在:" + tenant), source);
                close.setToTenantId(tenantId);
            }
        });
    }

    private void templateConvert(OpenCombineSyncDTO source) {
        Optional.ofNullable(source.getCost()).ifPresent(quote -> {
            if (LongUtils.notNullLong(quote.getTemplateId())) {
                var templateId = baseOpenDispatcherConversion.template(quote.getTemplateId());
                AssertUtils.assertNotNull(templateId, new ValueError("OpenCombineSyncDTO 合约不存在:" + quote.getTemplateId()), source);
                quote.setTemplateId(templateId);
            }
        });
    }

    private void areaConvert(OpenCombineSyncDTO source) {
        if (!CollectionUtils.isEmpty(source.getTransports())) {
            source.getTransports().forEach(data -> {
                if (StringUtils.isNotBlank(data.getWayProvince()) || StringUtils.isNotBlank(data.getWayCity()) || StringUtils.isNotBlank(data.getWayDistrict()) || StringUtils.isNotBlank(data.getWayTo())) {
                    var area = baseOpenDispatcherConversion.area(new AddressDTO(data.getWayProvinceCode() != null ? String.valueOf(data.getWayProvinceCode()) : null, data.getWayProvince(),
                            data.getWayCityCode() != null ? String.valueOf(data.getWayCityCode()) : null, data.getWayCity(),
                            data.getWayDistrictCode() != null ? String.valueOf(data.getWayDistrictCode()) : null, data.getWayDistrict(), data.getWayTo(), Constants.LEVEL));
                    AssertUtils.assertNotNull(area, new ValueError("OpenCombineSyncDTO 多段轨迹 地区不存在:" + data.getWayProvince() + "," + data.getWayCity() + "," + data.getWayDistrict() + "," + data.getWayTo()), source);
                    data.setWayProvinceCode(StringUtils.isNotBlank(area.getProvinceCode()) ? Long.valueOf(area.getProvinceCode()) : null);
                    data.setWayProvince(area.getProvinceName());
                    data.setWayCityCode(StringUtils.isNotBlank(area.getCityCode()) ? Long.valueOf(area.getCityCode()) : null);
                    data.setWayCity(area.getCityName());
                    data.setWayDistrictCode(StringUtils.isNotBlank(area.getDistrictCode()) ? Long.valueOf(area.getDistrictCode()) : null);
                    data.setWayDistrict(area.getDistrictName());
                    if (StringUtils.isBlank(data.getWayTo())) {
                        data.setWayTo("#");
                    }
                }
            });
        }
    }

}
